package com.core.sdk.extra.task;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpUriRequest;

import roboguice.util.RoboAsyncTask;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;

import com.core.sdk.utils.HttpUtil;
import com.core.sdk.utils.IOUtil;
import com.core.sdk.utils.ImageUtil;
import com.core.sdk.utils.HttpUtil.ParamSendType;

@SuppressWarnings("javadoc")
public class ImageLoadTask extends RoboAsyncTask<Bitmap> {

    String url = null;
    String savePath = null;
    OnImageLoadFinishCallBack callBack = null;
    Bundle param = new Bundle();
    public ImageLoadTask(Context context,String url,String savePath) {
        super(context);
        this.url = url;
        this.savePath = savePath;
    }

    @Override
    public Bitmap call() throws Exception {
        int newWidth = getImageWidth();
        if(IOUtil.fileExist(savePath)){
            if(IOUtil.getFileSize(savePath) > 1024){
                Bitmap bmp = null;
                if (newWidth != -1) {
                    bmp = ImageUtil.getBitmapFromFile(savePath, newWidth);
                } else {
                    bmp = ImageUtil.getBitmap(savePath);
                }
                if (bmp == null) {
                    throw new Exception("can't load bitmap from file:" + savePath+" url="+this.url);
                }
                return bmp;
            }else{
                IOUtil.delete(savePath);
            }
        }
        HttpUriRequest request = HttpUtil.buildRequest(url, HttpUtil.Method.GET,null,ParamSendType.text);
        HttpResponse response = HttpUtil.execute(request);
        int responseCode = response.getStatusLine().getStatusCode();
        FileOutputStream fos = null;
        if (responseCode == HttpStatus.SC_OK) {
            IOUtil.delete(getTmpDataFileName());
            fos = new FileOutputStream(getTmpDataFileName());
        } else if (responseCode == HttpStatus.SC_PARTIAL_CONTENT) {
            fos = IOUtil.getFileOutputStream(getTmpDataFileName(), true);
        } else if (responseCode == HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE) {
            IOUtil.delete(getTmpDataFileName());
        } else {
            IOUtil.delete(getTmpDataFileName());
        }
        if(fos == null)
            return null;
        saveDataToFile(response.getEntity().getContent(), fos,request);
        Bitmap bmp = null;
        IOUtil.rename(getTmpDataFileName(), savePath);
        if (newWidth != -1) {
            bmp = ImageUtil.getBitmapFromFile(savePath, newWidth);
        } else {
            bmp = ImageUtil.getBitmap(savePath);
        }
        if (bmp == null)
            throw new Exception("can't load bitmap from file:" + savePath);
        return bmp;
    }

    @Override
    protected void onSuccess(Bitmap t) throws Exception {
        super.onSuccess(t);
        if(this.callBack != null)
            this.callBack.onSuccess(t);
    }

    @Override
    protected void onException(Exception e) throws RuntimeException {
        super.onException(e);
        if(this.callBack != null)
            this.callBack.onException(e);
    }

    public void setCallBack(OnImageLoadFinishCallBack callBack) {
        this.callBack = callBack;
    }

    public void setImageWidth(int newWidth){
        param.putInt("width", newWidth);
    }
    public int getImageWidth(){
        return param.getInt("width", -1);
    }

    public String getTmpDataFileName() {
        if (savePath != null) {
            int c = savePath.lastIndexOf("/");
            String p = savePath.substring(0, c);
            File f = new File(p);
            if (!f.exists()) {
                f.mkdirs();
            }
        }
        int n = savePath.indexOf(".");
        return savePath.substring(0, n) + "_tmp" + savePath.substring(n);
    }
    private void saveDataToFile(InputStream is,FileOutputStream fos,HttpUriRequest request) throws IOException{
        try {
            byte[] buffer = new byte[1024];
            int n = -1;
            while((n = is.read(buffer, 0, buffer.length)) != -1){
                fos.write(buffer, 0, n);
                fos.flush();
            }
        }finally{
            closeFileOutPutStream(fos);
            closeInputStream(is,request);
        }
    }
    private void closeFileOutPutStream(FileOutputStream fos) {
        if (fos != null) {
            try {
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                fos = null;
            }
        }
    }

    private void closeInputStream(InputStream is, HttpUriRequest request) {
        if (is != null) {
            try {
                try {
                    request.abort();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                is = null;
            }
        }
    }
    public static interface OnImageLoadFinishCallBack{
        void onSuccess(Bitmap t);
        void onException(Exception e);
    }
    public String getUrl() {
        return url;
    }

}
